package jwtutil

import (
	"strconv"
	"time"

	"github.com/golang-jwt/jwt/v4"
)

// 标准声明键名
const (
	KeyUserId = "userId"
	KeyRole   = "role"
	KeyExp    = "exp"
	KeyIat    = "iat"
)

// CustomClaims 自定义 JWT 声明结构
type CustomClaims struct {
	UserId int64  `json:"userId"`
	Role   string `json:"role,omitempty"`
	jwt.RegisteredClaims
}

// GenerateToken 生成 JWT 令牌
// 生成只包含 ID 的令牌
func GenerateToken(secretKey string, expireSeconds int64, userId int64) (string, error) {
	now := time.Now()
	claims := jwt.RegisteredClaims{
		ExpiresAt: jwt.NewNumericDate(now.Add(time.Duration(expireSeconds) * time.Second)),
		IssuedAt:  jwt.NewNumericDate(now),
		Subject:   strconv.FormatInt(userId, 10), // 使用 subject 字段存储用户 ID
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	return token.SignedString([]byte(secretKey))
}

// ParseToken 解析 JWT 令牌
func ParseToken(tokenString, secretKey string) (*CustomClaims, error) {
	token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(secretKey), nil
	})

	if err != nil {
		return nil, err
	}

	if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
		return claims, nil
	}

	return nil, jwt.ErrSignatureInvalid
}

// GenerateTokenPair 生成访问令牌和刷新令牌对
func GenerateTokenPair(secretKey string, accessExpire, refreshExpire int64, userId int64) (accessToken, refreshToken string, err error) {
	// 生成访问令牌
	accessToken, err = GenerateToken(secretKey, accessExpire, userId)
	if err != nil {
		return "", "", err
	}

	// 生成刷新令牌 (通常不包含角色信息，只包含用户ID)
	refreshToken, err = GenerateToken(secretKey, refreshExpire, userId)
	if err != nil {
		return "", "", err
	}

	return accessToken, refreshToken, nil
}
